<?php
namespace App\Models;

use Maatwebsite\Excel\Facades\Excel;

class PrivateCode extends BaseModel
{
    protected $table = 'private_code';
    protected $length = 6;
    protected $max = 2000;

    protected $rules = [
        'code' => 'required|alpha_num|unique:private_code,code|size:6'
    ];

    protected $message = [
        'code.required' => '请输入客户订水码',
        'code.alpha_num' => '客户订水码只能为字母或数字',
        'code.unique' => '客户订水码重复',
        'code.size' => '客户订水码长度应为6'
    ];

    /**
     * 批量生成订水码
     * @return bool
     */
    public function multiCreateCode()
    {
        $num = intval(request('num'));
        if(!$num){
            $this->error = '请输入要生成的数量';
            return false;
        }
        if(!is_int($num)) {
            $this->error = '请输入正整数';
            return false;
        }
        if($num > $this->max){
            $this->error = '一次最多生成'.$this->max.'个';
            return false;
        }
        // 查询已存在的code
        $list = $this->_getList([],'code');
        $already = array_column($list->toArray(),'code');

        // 生成新的code
        $codes = [];
        $time = date('Y-m-d H:i:s');
        for($i = 0; $i< $num; $i ++){
            $codes[$i]['code'] = $this->getCode($already);
            $codes[$i]['created_at'] = $time;
        }
        $this->_start();
        try {
            $this->_add($codes);
            $this->_commit();
            return true;
        }catch(\Exception $e) {
            $this->_rollBack();
            $this->error = '批量生成客户订水码失败';
            return false;
        }
    }

    /**
     * 生成随机码
     * @param array $already
     * @return bool|string
     */
    protected function getCode(array $already)
    {
        $rangArea = '0123456789abcdefghijklmnopqrstuvwxyz';
        $str = substr(str_shuffle($rangArea),0, $this->length);
        if(in_array($str, $already)) {
            return $this->getCode($already);
        } else {
            return $str;
        }
    }

    public function getPrivateCodeList($where, $order = [],$pageSize = 20, $pageLength = 10)
    {
        $list = $this->_getPageList($where,'id,code,shop_id,mid,status,code_status',$order,$pageSize,$pageLength);
        if($list) {
            $shopIds = array_unique(array_filter(array_column($list['data'], 'shop_id')));
            $mids = array_unique(array_filter(array_column($list['data'], 'mid')));

            $shopWhere['id'] = ['in', $shopIds];
            $memberWhere['id'] = ['in', $mids];
            $shops = (new Shop())->_getList($shopWhere,'id,shop_name');
            $members = (new Member())->_getList($memberWhere,'id,nickname');
            $list['data'] = collect($list['data'])->map(function ($itemL) use($shops, $members) {
                $itemL['shop_name'] = '';
                $itemL['nickname'] = '';
                $itemL['status_text'] = $itemL['status'] == 1 ? '正常' : '失效';

                $shops->map(function ($itemS) use (&$itemL) {
                    if($itemL['shop_id'] == $itemS['id']){
                        $itemL['shop_name'] = $itemS['shop_name'];
                    }
                });

                $members->map(function ($itemM) use (&$itemL) {
                    if($itemL['mid'] == $itemM['id']){
                        $itemL['nickname'] = $itemM['nickname'];
                    }
                });

                return $itemL;
            })->toArray();
        }
        return $list;
    }

    // 导出功能
    public function exportPrivateExcel($data)
    {
        return Excel::create('客户订水码', function ($excel) use ($data) {
            $excel->sheet('private_code', function ($sheet) use ($data) {
                $sheet->rows($data);
            });
        })->export('xls');
    }

    // 订水码绑定用户
    public function bindUserByCode($userInfo, $private_code)
    {
        $result = [
            'status' => 1,
            'msg' => ''
        ];
        $privateInfo = $this->_getOne(['code'=>$private_code]);
        // 判断订水码是否绑定过店铺
        if(!$privateInfo) {
            $result['status'] = 0;
            $result['msg'] = '该客户订水码不存在';
        }
        if(!$privateInfo['shop_id'] || !$privateInfo['admin_id'] || $privateInfo['code_status'] == 1) {
            $result['status'] = 0;
            $result['msg'] = '该客户订水码未绑定店铺';
        }
        if(!$privateInfo['status']) {
            $result['status'] = 0;
            $result['msg'] = '该客户订水码已失效';
        }
        if(!isset($userInfo['openid'])) {
            $result['status'] = 0;
            $result['msg'] = '获取用户信息失败，请重新扫码！';
        }
        if(!$result['status']) {
            return $result;
        }


        // 查询当前用户信息
        $memberModel = (new Member());
        $currentMember = $memberModel->_getOne(['wx_openid' => $userInfo['openid'], 'shop_id' => $privateInfo['shop_id']]);

        // 判断该订水码是否已经绑定用户
        if(!$privateInfo['mid'] || $privateInfo['code_status'] != 3) {
            // 未绑定时，当前账号为主账号
            if(!$currentMember) {
                // 当前账号不存在时，直接将当前账号绑定到对应订水码的店铺，并绑定此订水码
                $memberData = [
                    'admin_id' => in_array($privateInfo['admin_id'],[1,2]) ? 2 : $privateInfo['admin_id'],
                    'shop_id' => $privateInfo['shop_id'],
                    'xcx_openid' => md5(time()),
                    'wx_openid' => $userInfo['openid'],
                    'is_default' => 1,
                    'unionid' => isset($userInfo['unionid']) ? $userInfo['unionid'] : '',
                    'nickname' => $userInfo['nickname'],
                    'avatarurl' => $userInfo['headimgurl'],
                    'addtime' => time(),
                ];
                $mid = $memberModel->_save($memberData);
                if(!$mid) {
                    $result['status'] = 0;
                    $result['msg'] = '主账号绑定失败';
                } else {
                    $updateData = [
                        'mid' => $mid,
                        'code_status' => 3
                    ];
                    $res = $this->_update(['code' => $private_code], $updateData);
                    if(!$res) {
                        $result['status'] = 0;
                        $result['msg'] = '主账号绑定失败';
                    } else {
                        $params = '&wx_openid=' . $userInfo['openid'] . '&sid=' . $privateInfo['shop_id'].'&buyer_openid='.$userInfo['openid'];
                        $url = url('/client/water-index.html?_=' . time() . $params);
                        $result['msg'] = $url;
                    }
                }
            } else {
                //判断当前账号是否绑定过其他未禁用的订水码
                $info = $this->_getOne(['shop_id' => $privateInfo['shop_id'], 'mid' => $currentMember['id'], 'status' => 1]);
                if(!$info) {
                    $updateData = [
                        'mid' => $currentMember['id'],
                        'code_status' => 3
                    ];
                    // 主账号绑定订水码
                    $res = $this->_update(['code' => $private_code], $updateData);
                    if(!$res) {
                        $result['status'] = 0;
                        $result['msg'] = '主账号绑定失败';
                    } else {
                        $params = '&wx_openid=' . $userInfo['openid'] . '&sid=' . $privateInfo['shop_id'].'&buyer_openid='.$userInfo['openid'];
                        $url = url('/client/water-index.html?_=' . time() . $params);
                        $result['msg'] = $url;
                    }
                } else {
                    $result['status'] = 0;
                    $result['msg'] = '当前账号已绑定过客户订水码';
                }
            }
        } else {
            // 已绑定时，当前账号为从账号
            $primaryMember = $memberModel->_getOneById($privateInfo['mid']);
            if(!$primaryMember) {
                $result['status'] = 0;
                $result['msg'] = '主账号不存在';
            } else {
                $params = '&wx_openid=' . $primaryMember['wx_openid'] . '&sid=' . $privateInfo['shop_id'].'&buyer_openid='.$userInfo['openid'];
                $url = url('/client/water-index.html?_=' . time() . $params);

                // 判断从账号是否存在
                if($currentMember) {
                    $result['msg'] = $url;
                } else {
                    // 入库操作
                    $newMemberInfo = [
                        'admin_id' => in_array($privateInfo['admin_id'],[1,2]) ? 2 : $privateInfo['admin_id'],
                        'shop_id' => $privateInfo['shop_id'],
                        'xcx_openid' => md5(time()),
                        'wx_openid' => $userInfo['openid'],
                        'is_default' => 1,
                        'unionid' => isset($userInfo['unionid']) ? $userInfo['unionid'] : '',
                        'nickname' => $userInfo['nickname'],
                        'avatarurl' => $userInfo['headimgurl'],
                        'addtime' => time(),
                    ];
                    $res = $memberModel->_save($newMemberInfo);
                    if(!$res) {
                        $result['status'] = 0;
                        $result['msg'] = '操作失败';
                    } else {
                        $result['msg'] = $url;
                    }
                }
            }
        }

        return $result;
    }

    // 店铺绑定订水二维码
    public function bindShopCode()
    {
        $shop_id = request('shop_id');
        $id_start = request('id_start');
        $id_end = request('id_end');
        if(!is_numeric($id_start) || !is_numeric($id_end)) {
            $this->error = '初始序号或结束序号应为数字';
            return false;
        }
        if(!$id_start || !$id_end) {
            $this->error = '请输入初始序号或结束序号';
            return false;
        }
        if($id_start > $id_end) {
            $this->error = '初始序号不得大于结束序号';
            return false;
        }
        $shopInfo = (new Shop())->_getOneById($shop_id);
        if(!$shopInfo) {
            $this->error = '该店铺不存在';
            return false;
        }
        // 判断序号范围内是否有已绑定的数据
        $whereOrigin['id'] = ['between', [$id_start, $id_end]];
        $whereOrigin['code_status'] = 1;
        $unBindCount = $this->_count($whereOrigin,'id');
        unset($whereOrigin['code_status']);
        $originCount = $this->_count($whereOrigin,'id');
        if($unBindCount != $originCount) {
            $this->error = '序号范围内有已绑定的数据';
            return false;
        }

        $updateData = [
            'shop_id' => $shop_id,
            'admin_id' => $shopInfo['admin_id'],
            'code_status' => 2
        ];
        // 只有未绑定店铺的订水码才能进行绑定操作
        $where['id'] = ['between',[$id_start, $id_end]];
        $where['code_status'] = 1;
        $where['status'] = 1;
        $where['shop_id'] = 0;
        $where['admin_id'] = 0;
        $this->_start();
        try{
            $this->_update($where, $updateData);
            $this->_commit();
        } catch(\Exception $e){
            $this->_rollBack();
            $this->error = '客户订水码绑定失败';
            return false;
        }
        return true;
    }
}